/// 布局页 * 主界面

import { ConfigProvider, Layout, Menu } from 'ant-design-vue'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
import type { VNode } from 'vue'
import { KeepAlive, Transition } from 'vue'
import type { OnResize } from '@expresso/plus'
import {
  ExIcon,
  ExLoading,
  ExpressoPlusConfig,
  genComponent,
  setGridBtnDisplay,
} from '@expresso/plus'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
import { RouterView } from 'vue-router'
import type { ModalFunc } from 'ant-design-vue/es/modal/confirm'
import PerfectScrollbar from 'perfect-scrollbar'
import 'perfect-scrollbar/css/perfect-scrollbar.css'
import { mainCSS } from './styles'
import MenusRight from './components/MenusRight/Index'
import type { PagebarExpose } from './components/Pagebar/Index'
import Pagebar from './components/Pagebar/Index'
import router from '@/router'
import { useLoginStore, useMenusStore } from '@/stores'
import 'dayjs/locale/zh-cn'
import { cache } from '@/helpers'

//# 定义

/**
 * 主界面
 */
export default genComponent({ name: 'Main' }, () => {
  //# 成员

  /** 路由 */
  const route = useRoute()

  /** 加载器（全局） */
  const loading = useLoading()

  //// 全局状态 ////

  /** 全局状态-登录 */
  const login = useLoginStore()
  //|
  /** 全局状态-菜单 */
  const menus = useMenusStore()

  //// 布局 ////

  /** 侧边 */
  const sider = shallowReactive<{
    scrollbar: Ref<HTMLDivElement | undefined>
    ps?: PerfectScrollbar
    width: Key
    expand: () => void
    collapse: () => void
    onResize: OnResize
  }>({
    scrollbar: ref(),
    width: 0,
    onResize(/* data, target */) {
      sider.ps?.update()
    },
    expand() {
      sider.width = 216
    },
    collapse() {
      sider.width = 0
    },
  })
  {
    ExpressoPlusConfig.layouts.main.sider = sider
  }

  /** 页签栏-引用 */
  const pagebarRef = ref<PagebarExpose>()
  //|
  /** 页签栏 */
  const pagebar = {
    tags: computed(() =>
      menus.records.list.map(
        ({ url, cachable }) => (
          cachable && url ? url.toLocaleLowerCase() : ''
        ),
      ).filter(Boolean),
    ),
    cache: new Map<string, VNode>(),
    genPage(node: VNode, route: RouteLocationNormalizedLoaded) {
      if (!node) {
        return
      }

      let page = node
      if (!['Redirect', 'NotFoundException'].includes((node.type as any).name)) {
        const pageTag = route.path.toLocaleLowerCase()

        if (pagebar.cache.has(pageTag)) {
          page = pagebar.cache.get(pageTag)!
        }
        else {
          page = h({
            name: pageTag,
            setup() {
              return () => <div class="wh-100p">{node}</div>
            },
          })
          pagebar.cache.set(pageTag, page)
          useMenusStore.path2fullPath[pageTag] = route.fullPath
        }
      }

      pagebar.cache.forEach((_, key) => {
        if (!pagebar.tags.value.includes(key.toLocaleLowerCase())) {
          pagebar.cache.delete(key)
          delete useMenusStore.path2fullPath[key]
        }
      })

      return page
    },
  }

  //# 周期

  let confirmChangePassword: ReturnType<ModalFunc> | undefined
  onMounted(async () => {
    sider.ps = new PerfectScrollbar(sider.scrollbar.value!, {
      suppressScrollX: true,
      scrollYMarginOffset: 3,
    })

    setTimeout(() => {
      sider.expand()
    }, 50)
    if (login.user.status == 0) {
      confirmChangePassword = Message.confirm({
        title: '系统提示',
        content: '为了您的账号安全，请及时到个人中心修改登录密码',
        onOk() {
          router.push('/user-center')
        },
        afterClose() {
          cache.setLoginInfo({
            ...(cache.getLoginInfo() ?? ({} as any)),
            userStatus: 1,
          })
        },
      })
    }
  })

  onUnmounted(() => {
    confirmChangePassword?.destroy()
  })

  /* 监听 路径 */
  watch(
    () => route.path,
    (path) => {
      if (path === '/') {
        const defaultPath = '' // '/project/index'
        const path = menus.initMenus(defaultPath)
        path && router.push(path)
      }
      else {
        path = path.toLocaleLowerCase()
        if (route.name === 'NotFoundException') {
          return
        }
        else if (!path.startsWith('/redirect/')) {
          const url = menus.initMenus(path)
          if (url) {
            menus.appendRecord(url, 'url')
          }
          else {
            menus.addRecord(route.path, route.meta?.title as any)
          }

          if (
            path.startsWith('/iot/')
            || path.startsWith('/dataease/')
            || path.startsWith('/business/')
            || (path.startsWith('/project/') && path !== '/project/pro-list')
          ) {
            const promise = login.loadProject()
            if (!login.project.options) {
              promise.finally(() => {
                setTimeout(() => {
                  pagebarRef.value?.refresh()
                })
              })
            }
          }
          else {
            login.resetProject()
          }
          setGridBtnDisplay(menus.btns[path] ?? {})
        }
        router.replace(route.fullPath)
      }
    },
    { immediate: true },
  )

  //# 渲染
  return () => (
    <ConfigProvider locale={zhCN}>
      {/* 主体 */}
      <Layout class={['main', mainCSS]}>
        {/* 主体-头 */}
        <Layout.Header class="header">
          <div class="menusbar">
            {/* 首页菜单 */}
            <div class="menu-home" onClick={() => router.replace('/home')}>
              <ExIcon type="hd-icon-shouye" size={30} />
            </div>
            {/* 一级菜单集 */}
            <div class="menus">
              <Menu
                mode="horizontal"
                theme="dark"
                selectedKeys={menus.keys.level1Keys}
                onSelect={({ selectedKeys }) => {
                  const selectedKey = (menus.keys.level1Keys = selectedKeys)[0]
                  const menu = menus.data.level1Key2Menus[selectedKey]?.[0]
                  menu && menus.openMenu(menu)
                }}
              >
                {menus.menusLevel1.top.map(({ key, label }) => (
                  <Menu.Item key={key}>{label}</Menu.Item>
                ))}
              </Menu>
            </div>
            {/* 右侧菜单集 */}
            <MenusRight />
          </div>
        </Layout.Header>
        {/* 主体-体 */}
        <Layout class="body">
          {/* 主体-体-侧边 */}
          <Layout.Sider class="sider" width={sider.width}>
            {/* 菜单 */}
            <div class="scrollbar" v-resize={sider.onResize} ref={sider.scrollbar}>
              <Menu
                v-resize={sider.onResize}
                selectedKeys={menus.keys.levelsKeys}
                openKeys={menus.keys.openKeys}
                mode="inline"
                theme="dark"
                items={menus.menusLevels}
                inlineIndent={28}
                onOpenChange={openKeys => (menus.keys.openKeys = openKeys)}
                onSelect={({ selectedKeys }) => {
                  menus.openMenu((menus.keys.levelsKeys = selectedKeys)[0])
                }}
              />
            </div>
          </Layout.Sider>
          {/* 主体-体-内容 */}
          <Layout.Content class="content">
            {/* 页签栏 */}
            <Pagebar ref={pagebarRef} />
            {/* 页面 */}
            <ExLoading class="page" loading={loading.value}>
              <RouterView>
                {{
                  default: ({
                    Component,
                    route,
                  }: {
                    Component: VNode
                    route: RouteLocationNormalizedLoaded
                  }) => (
                    <Transition name="fade-transform" mode="out-in">
                      <KeepAlive
                        include={pagebar.tags.value}
                        exclude={['Redirect', 'NotFoundException']}
                      >
                        {pagebar.genPage(Component, route)}
                      </KeepAlive>
                      {/* {
                        pagebar.tags.value.includes(route.path.toLocaleLowerCase())
                          ? (
                              <KeepAlive include={pagebar.tags.value} exclude={['Redirect']}>
                                {pagebar.genPage(Component, route)}
                              </KeepAlive>
                            )
                          : Component
                      } */}
                    </Transition>
                  ),
                }}
              </RouterView>
            </ExLoading>
          </Layout.Content>
        </Layout>
      </Layout>
    </ConfigProvider>
  )
})
